#pragma once 
#include <bits/stdc++.h>

/*****************************************************************************
 *! @brief nique_ptr本质是进制了拷贝和赋值构造函数的shared_ptr, 但运行移动构造.
 *
 *
 *         
 *           
 * 
 *  
 ****************************************************************************/


//! 实现make_unique
// 1. 普通指针
template<typename T, typename... Args> inline 
typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type 
make_unique(Args&&... args) {
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}

// 2. 动态数组
//! std::extent<T, N>::value  返回数组第N维的代销, std::extent<T>::value 则返回最外层大小
template<typename T> inline 
typename std::enable_if<std::is_array<T>::value && std::extent<T>::value == 0, std::unique_ptr<T>>::type 
make_unique(size_t size) {
    using U = typename std::remove_extent<T>::type;
    return std::unique_ptr<T>(new U[size]());
}

// 3. 过滤掉定长数组
template<typename T, typename... Args> inline 
typename std::enable_if<std::extent<T>::value != 0, void>::type 
make_unique(Args... args) = delete;

int std_unique_ptr();